﻿using Microsoft.Practices.Prism.Logging ;
using Microsoft.Practices.Prism.MefExtensions ;
using Microsoft.Practices.Prism.Modularity ;
using OpenLightGroup.Common ;
using OpenLightGroup.Prism ;
using System.ComponentModel.Composition.Hosting ;
using System.ComponentModel.Composition ;
using System.Windows ;

namespace PrismExample
{
    public class Bootstrapper : MefBootstrapper
    {

        protected override void ConfigureAggregateCatalog ( )
        {
            base.ConfigureAggregateCatalog( ) ;

            //Add all exports from current assembly
            this.AggregateCatalog.Catalogs.Add( new AssemblyCatalog( typeof(Bootstrapper).Assembly ) ) ;

            //replace default MefXapModuleTypeLoader with our Caching version
            this.AggregateCatalog.Catalogs.Add( new TypeCatalog( typeof(CachingMefXapModuleTypeLoader) ) ) ;

            //replace default MefModuleManager with our Synchronizing version. This is required sense we are using a ISynchronizingModuleCatalog
            this.AggregateCatalog.Catalogs.Add( new TypeCatalog( typeof(SynchronizingMefModuleManager) ) ) ;

        }

        protected override void ConfigureContainer ( )
        {
            base.ConfigureContainer( ) ;

            //Registering the instance of our logger to ensure that a new one is not created by the container.
            // We only need to register the instance with the ICompositeLogger interface because the base method will configure the instance for ILoggerFacade
            this.Container.ComposeExportedValue<ICompositeLogger>( this.Logger as ICompositeLogger ) ;

            //Add an instance of NetworkStatus to the container so that it can be imported where needed.
            this.Container.ComposeExportedValue<INetworkStatus>( NetworkStatus.Current ) ;
        }

        protected override ILoggerFacade CreateLogger ( )
        {
            //We create a new CompositeLogger to use as the ILoggerFacade
            CompositeLogger compositeLogger = new CompositeLogger( ) ;

            //We then register an instance for each logger we want to use
            compositeLogger.RegisterLogger( "DebugLogger", new DebugLogger( ) ) ;
            compositeLogger.RegisterLogger( "IsoStorageLogger", new IsolatedStorageLogger( ) ) ;
            compositeLogger.RegisterLogger( "StringCollectionLogger", new StringCollectionLogger( ) ) ;

            compositeLogger.Log( " *** Application Starting ***", Category.Debug, Priority.Low ) ;

            return compositeLogger ;
        }

        protected override IModuleCatalog CreateModuleCatalog ( )
        {
            //WebModuleCatalog is a ISynchronizingModuleCatalog, 
            // so we must replace default MefModuleManager with 
            // our Synchronizing version to ensure modules get loaded when the catalog is updated.
            return new WebModuleCatalog( this.Logger ) ;
        }

        protected override DependencyObject CreateShell ( )
        {
            //Get Shell from container
            return this.Container.GetExportedValue<Shell>( ) ;
        }

        protected override void InitializeShell ( )
        {
            //Set Shell as the RootVisual
            App.Current.RootVisual = this.Shell as UIElement ;
        }

    }
}